/*
Copyright [2020] [https://www.xiaonuo.vip]

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

  http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

Snowy采用APACHE LICENSE 2.0开源协议，您在使用过程中，需要注意以下几点：

1.请不要删除和修改根目录下的LICENSE文件。
2.请不要删除和修改Snowy源码头部的版权声明。
3.请保留源码和相关描述文件的项目出处，作者声明等。
4.分发源码时候，请注明软件出处 https://gitee.com/xiaonuobase/snowy
5.在修改包名，模块名称，项目代码等时，请注明软件出处 https://gitee.com/xiaonuobase/snowy
6.若您的项目无法满足以上几点，可申请商业授权，获取Snowy商业授权许可，请在官网购买授权，地址为 https://www.xiaonuo.vip
 */
package vip.xiaonuo.modular.puororder.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.lang.Console;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import vip.xiaonuo.core.exception.ServiceException;
import vip.xiaonuo.core.factory.PageFactory;
import vip.xiaonuo.core.pojo.page.PageResult;
import vip.xiaonuo.core.util.PoiUtil;
import vip.xiaonuo.modular.puordetail.entity.PuorDetail;
import vip.xiaonuo.modular.puordetail.mapper.PuorDetailMapper;
import vip.xiaonuo.modular.puordetail.service.PuorDetailService;
import vip.xiaonuo.modular.puororder.Result.PuorOrderResult;
import vip.xiaonuo.modular.puororder.entity.PuorOrder;
import vip.xiaonuo.modular.puororder.enums.PuorOrderExceptionEnum;
import vip.xiaonuo.modular.puororder.mapper.PuorOrderMapper;
import vip.xiaonuo.modular.puororder.param.PuorOrderParam;
import vip.xiaonuo.modular.puororder.service.PuorOrderService;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import vip.xiaonuo.util.AutoCode;

import javax.annotation.Resource;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 采购订单service接口实现类
 *
 * @author jiaxin
 * @date 2022-07-27 15:27:15
 */
@Service
public class PuorOrderServiceImpl extends ServiceImpl<PuorOrderMapper, PuorOrder> implements PuorOrderService {
    @Resource
    private PuorDetailService puorDetailService;

    @Override
    public PageResult<PuorOrderResult> page(PuorOrderParam puorOrderParam) {
        QueryWrapper<PuorOrder> queryWrapper = new QueryWrapper<>();
        if (ObjectUtil.isNotNull(puorOrderParam)) {
            // 根据采购订单编码 查询
            if (ObjectUtil.isNotEmpty(puorOrderParam.getCode())) {
                queryWrapper.like("a.code", puorOrderParam.getCode());
            }
            // 根据到货时间 查询
            if (ObjectUtil.isNotEmpty(puorOrderParam.getArrivalTime())) {
                SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
                Date date = new Date();
                try {
                    date = sdf.parse(puorOrderParam.getArrivalTime());
                } catch (ParseException e) {
                    e.printStackTrace();
                }
                //得到日历
                Calendar calendar = Calendar.getInstance();
                //把当前时间赋给日历
                calendar.setTime(date);
                queryWrapper.lambda().ge(PuorOrder::getArrivalTime, sdf.format(calendar.getTime()));
                //设置为后一天
                calendar.add(Calendar.DAY_OF_MONTH, +1);
                queryWrapper.lambda().lt(PuorOrder::getArrivalTime, sdf.format(calendar.getTime()));

            }
            // 根据订单来源 查询
            if (ObjectUtil.isNotEmpty(puorOrderParam.getOrderSource())) {
                queryWrapper.lambda().eq(PuorOrder::getOrderSource, puorOrderParam.getOrderSource());
            }
            // 根据备注 查询
            if (ObjectUtil.isNotEmpty(puorOrderParam.getRemarks())) {
                queryWrapper.lambda().like(PuorOrder::getRemarks, puorOrderParam.getRemarks());
            }
        }
        queryWrapper.orderByDesc("a.create_time");
        Page<PuorOrderResult> page=baseMapper.page(PageFactory.defaultPage(), queryWrapper);
        List<PuorDetail> puorDetailList=puorDetailService.list();
        Map<Long,List<PuorDetail>> puorDetailGroupByOrderId=puorDetailList.stream().collect(Collectors.groupingBy(PuorDetail::getPurchaseOrderId));
        page.getRecords().forEach(item -> {
            Long id = item.getId();
            if (ObjectUtil.isEmpty(id)) {
                return;
            }
            List<PuorDetail> puorDetails = puorDetailGroupByOrderId.get(item.getId());
            if (ObjectUtil.isEmpty(puorDetails)) {
                return;
            }
            item.setPuorDetailList(puorDetails);
        });
        return new PageResult<>(page);
    }

    @Override
    public List<PuorOrder> list(PuorOrderParam puorOrderParam) {
        return this.list();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void add(PuorOrderParam puorOrderParam) {
        //采购订单不能为空
        if (ObjectUtil.isEmpty(puorOrderParam)){
            throw new ServiceException(1,"采购订单不能为空");
        }
        checkParam(puorOrderParam,false);
        //如果采购订单编码为空，自动生成编码
        if (ObjectUtil.isEmpty(puorOrderParam.getCode())){
            puorOrderParam.setCode(AutoCode.getCodeByService("dw_puor_order", this.getClass(), 0));
        }
        PuorOrder puorOrder = new PuorOrder();
        BeanUtil.copyProperties(puorOrderParam, puorOrder);
        this.save(puorOrder);
        for (PuorDetail puorDetail : puorOrderParam.getPuorDetailList()) {
            //给生产细明赋采购订单id
            puorDetail.setPurchaseOrderId(puorOrder.getId());
            //生成生产细明编码
            puorDetail.setCode(AutoCode.getCodeByService("dw_puor_detail", puorDetailService.getClass(), 0));
        }
        //添加采购明细
        puorDetailService.saveBatch(puorOrderParam.getPuorDetailList());
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void delete(List<PuorOrderParam> puorOrderParamList) {
        QueryWrapper<PuorDetail> deletePuorDetailQuery = new QueryWrapper<>();
        List<Long> deleteDetails=new ArrayList<>();
        puorOrderParamList.forEach(puorOrderParam->{
            if (ObjectUtil.isNotEmpty(puorOrderParam.getPuorDetailList())){
                puorOrderParam.getPuorDetailList().forEach(item->{
                    deletePuorDetailQuery.lambda().eq(PuorDetail::getId,item.getId());
                });
            }
            Console.log("要删除的采购订单id"+puorOrderParam.getId());
            deleteDetails.add(puorOrderParam.getId());
        });
        //删除采购明细
        puorDetailService.remove(deletePuorDetailQuery);
        //删除采购订单
        this.removeByIds(deleteDetails);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void edit(PuorOrderParam puorOrderParam) {
        checkParam(puorOrderParam,false);
        //编码不能为空
        if (ObjectUtil.isEmpty(puorOrderParam.getCode())){
            throw new ServiceException(9,"采购订单编码不能为空");
        }
        PuorOrder puorOrder = this.queryPuorOrder(puorOrderParam);
        BeanUtil.copyProperties(puorOrderParam, puorOrder);
        //更新采购订单
        this.updateById(puorOrder);
        Long id=puorOrderParam.getId();
        //要新增的采购明细
        List<PuorDetail> addDetails = new ArrayList<>();
        //要删除的采购明细
        List<Long> deleteDetails=new ArrayList<>();
        //要编辑的采购明细
        List<PuorDetail> editDetails = new ArrayList<>();
        //取出前端传来的采购订单明细
        List<PuorDetail> newPuorDetailList=puorOrderParam.getPuorDetailList();
        //查找数据库该采购订单里原有的明细
        QueryWrapper<PuorDetail> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(PuorDetail::getPurchaseOrderId, id);
        List<PuorDetail> oldPuorDetailList = puorDetailService.list(queryWrapper);
        for (PuorDetail puorDetail : newPuorDetailList) {
            //如果明细id不存在则为新添加的明细
            if (ObjectUtil.isEmpty(puorDetail.getId())){
                puorDetail.setPurchaseOrderId(id);
                puorDetail.setCode(AutoCode.getCodeByService("dw_puor_detail", this.getClass(), 0));
                addDetails.add(puorDetail);
            }
            //如果明细id存在则进行修改
            if (ObjectUtil.isNotEmpty(puorDetail.getId())){
                Iterator it=oldPuorDetailList.iterator();
                while (it.hasNext()){
                    PuorDetail puorDetailList= (PuorDetail) it.next();
                    if(puorDetailList.getId().equals(puorDetail.getId())){
                        it.remove();
                    }
                }
                //更新采购明细
                editDetails.add(puorDetail);
            }
        }
        //剩下的进行删除操作
        if (ObjectUtil.isNotEmpty(oldPuorDetailList)){
            for (PuorDetail puorDetail : oldPuorDetailList) {
                //删除明细
                deleteDetails.add(puorDetail.getId());
            }
        }
        //更新明细
        puorDetailService.updateBatchById(editDetails);
        //新增明细
        puorDetailService.saveBatch(addDetails);
        //删除明细
        puorDetailService.removeByIds(deleteDetails);


    }

    @Override
    public PuorOrder detail(PuorOrderParam puorOrderParam) {
        return this.queryPuorOrder(puorOrderParam);
    }

    /**
     * 获取采购订单
     *
     * @author jiaxin
     * @date 2022-07-27 15:27:15
     */
    private PuorOrder queryPuorOrder(PuorOrderParam puorOrderParam) {
        PuorOrder puorOrder = this.getById(puorOrderParam.getId());
        if (ObjectUtil.isNull(puorOrder)) {
            throw new ServiceException(PuorOrderExceptionEnum.NOT_EXIST);
        }
        return puorOrder;
    }

    @Override
    public void export(PuorOrderParam puorOrderParam) {
        List<PuorOrder> list = this.list(puorOrderParam);
        PoiUtil.exportExcelWithStream("SnowyPuorOrder.xls", PuorOrder.class, list);
    }
    private void checkParam(PuorOrderParam puorOrderParam, boolean isExcludeSelf) {
        //校验数据是否为空
        if (ObjectUtil.isEmpty(puorOrderParam.getArrivalTime())) {
            throw new ServiceException(2, "到货时间不能为空");
        }
        if (ObjectUtil.isEmpty(puorOrderParam.getOrderSource())) {
            throw new ServiceException(3, "采购订单来源不能为空");
        }
        for (PuorDetail puorDetail : puorOrderParam.getPuorDetailList()) {
            if (ObjectUtil.isEmpty(puorDetail.getProId())) {
                throw new ServiceException(4, "产品不能为空，请添加产品");
            }
            if (ObjectUtil.isEmpty(puorDetail.getPurchaseNum()) || puorDetail.getPurchaseNum() <= 0) {
                throw new ServiceException(5, "采购订单产品数量不能为空并且必须大于零，请重新输入");
            }
            if (ObjectUtil.isEmpty(puorDetail.getUnitPrice()) || puorDetail.getUnitPrice()<= 0){
                throw new ServiceException(6, "采购订单产品单价不能为空并且必须大于零，请重新输入");
            }
            if (ObjectUtil.isEmpty(puorDetail.getTotalPrice()) || puorDetail.getTotalPrice()<= 0){
                throw new ServiceException(7, "采购订单产品总价不能为空并且必须大于零，请重新输入");
            }
        }
        LambdaQueryWrapper<PuorOrder> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        //如果是编辑需要去除自己
//        if (isExcludeSelf) {
//            lambdaQueryWrapper.ne(PuorOrder::getId, puorOrderParam.getId());
//        }
        lambdaQueryWrapper.eq(PuorOrder::getCode, puorOrderParam.getCode());
        int count = this.count(lambdaQueryWrapper);
        if (count >= 2) {
            throw new ServiceException(8, "唯一编号已存在");
        }


    }
}
